#include "matrix_keys.h"


/*
  行给低电平，列上的那个按键按下就是低电平
  间隔10ms轮询行和列 - 行列置为0
 */

// 用16位二进制存上次状态
u16 last_state = 0xffff;


// 矩阵键盘引脚配置
void GPIO_Matrix_Key_Config(){
	GPIO_InitTypeDef init;
	
	// 配置P0.x
	init.Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	// 端口模式
	init.Mode = GPIO_PullUp;
	// 端口初始化
	GPIO_Inilize(GPIO_P0, &init);
	
	// 配置P2.x
	init.Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_7; 
	init.Mode = GPIO_PullUp;
	GPIO_Inilize(GPIO_P2, &init);
	
	// 配置P5.x
	init.Pin = GPIO_Pin_0 | GPIO_Pin_3;
	init.Mode = GPIO_PullUp;
	GPIO_Inilize(GPIO_P5, &init);
}


// 只将对应行置零
void row_set0_(u8 i){
	ROW1 = i == 0 ? 0:1;
	ROW2 = i == 1 ? 0:1;
	ROW3 = i == 2 ? 0:1;
	ROW4 = i == 3 ? 0:1;
}

// 找到对应列
u8 col_(u8 j){
	if(j==0) return COL1;
	if(j==1) return COL2;
	if(j==2) return COL3;
	if(j==3) return COL4;
	return COL1;
}


// 用数组存上次状态              16个
// u8 last_statep[16] = {UP, UP, ... , UP};
// 用二位4进制的高位表示i，低位表示j，转换为10进制就是数组对应ij的下标

// 轮询查询哪个按键按下
void polling_keys(void (*key_down_fun)(u8 row, u8 col), void (*key_up_fun)(u8 row, u8 col)){
	int i, j;
	// 行轮询
	for(i = 0; i <= 3; i++){
		// 设置对应行为低电平
		row_set0_(i);
		// 列轮询
		for(j = 0; j <= 3; j++){
			// 1左移之后不能用==1来判断，用>1才能判断
			if(col_(j) == DOWN  && IS_KEY_UP(i, j)){
				SET_KEY_DOWN(i, j);
				// 这里调用按键按下的外部函数
				// MK_key_down(i, j);
				if(key_down_fun != NULL){
					key_down_fun(i, j);
				}
			}
			// 1左移之后==0来判断是可以的
			if(col_(j) == UP  && IS_KEY_DOWN(i, j)){
				SET_KEY_UP(i, j);
				// 这里调用按键弹起的外部函数
				// MK_key_up(i, j);
				if(key_up_fun != NULL){
					key_up_fun(i, j);
				}
			}
		}	
	}
}
